package com.wgo.precise.client.ui.view.delegates;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.IProgressService;

import remato.client.controller.ClientSession;
import remato.client.controller.ModelStatus;
import remato.client.controller.RequirementPlugin;
import remato.client.controller.exceptions.RematoClientException;
import remato.client.view.session.LoginDialog;
import remato.client.view.util.ReflectionHelper;
import remato.client.view.util.ReflectionRunnableWithProgress;
import remato.client.view.util.ViewerAction;

import com.wgo.precise.client.common.session.ISessionHolder;
import com.wgo.precise.client.common.session.PreciseSession;

/**
 * @author petterei
 *
 */
public class ResetDatabaseActionDelegate extends Action implements IWorkbenchWindowActionDelegate {

	private ResetDatabaseAction resetDbAction;
	
	public void dispose() {
		resetDbAction.disposeSession();
		resetDbAction = null;
	}

	public void init(IWorkbenchWindow window) {
		resetDbAction = new ResetDatabaseAction(window) ;
	}

	public void run(IAction action) {
		resetDbAction.run();
	}

	public void selectionChanged(IAction action, ISelection selection) {
	}

}

class ResetDatabaseAction extends ViewerAction implements ISessionHolder<ClientSession> {

	private LoginDialog loginDialog;
	
	private PreciseSession session;
	
	public ResetDatabaseAction(IWorkbenchWindow window) {
		super("Reset server database.", PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_WARN_TSK));
		init(window);
	}

    public void init(IWorkbenchWindow window) {
        loginDialog = new LoginDialog(window.getShell(),this, "Reset Database", "Enter the url of where the database shall be resetted.");
        setToolTipText("Reset server database.");
    }

    @Override
    public void run() {
    	RequirementPlugin plugin = RequirementPlugin.getInstance();
    	if (plugin.isSessionSet()) {
    		if (plugin.getSession().isDirty()) {
    			MessageDialog dialog = new MessageDialog(RequirementPlugin.getInstance().getActiveShell(),
    					"Save existin session?", null, "You are currently logged in. Save unsaved changes?",
    					MessageDialog.QUESTION, new String[] {
    				IDialogConstants.OK_LABEL,
    				IDialogConstants.NO_LABEL,
    				IDialogConstants.CANCEL_LABEL }, 0);
    			switch (dialog.open()) {
    			case 0:
    				plugin.disposeSession(true);
    				break;
    			case 1:
    				plugin.disposeSession(false);
    				break;
    			case 2:
    				return;
    			}
    		} else {
    			plugin.disposeSession(false);
    		}
    	}
    	int result = loginDialog.open(); 
    	if (Window.OK == result) {
    		if (null != session) {
    			MessageDialog dialog = new MessageDialog(RequirementPlugin.getInstance().getActiveShell(),
    					"Really reset database?", null, "This will delete all contents at '" + session.getServerContextUrl() + "'. Are you sure this is what you want?",
    					MessageDialog.QUESTION, new String[] {
    				IDialogConstants.OK_LABEL,
    				IDialogConstants.CANCEL_LABEL }, 0);
    			switch (dialog.open()) {
    			case 0:
    				IRunnableWithProgress op = new ReflectionRunnableWithProgress("Resetting DB at " + session.getServerContextUrl(), ReflectionHelper.retrieveMethod(getClass().getSimpleName(), session.getClass(), "createDbSchema"),session);
    				IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
    				try {
						progressService.busyCursorWhile(op);
//    					new ProgressMonitorDialog(RequirementPlugin.getInstance().getActiveShell()).run(true,false,op);
    				} catch (InvocationTargetException e) {
    					RequirementPlugin.log(new ModelStatus(IStatus.ERROR, "Error resetting DB.", e));
    				} catch (InterruptedException e) {
    					RequirementPlugin.log(new ModelStatus(IStatus.ERROR, "Error resetting DB.", e));
    				}
    				break;
    			default:
    				return;
    			}
    		} else {
        		RequirementPlugin.log(new ModelStatus(IStatus.WARNING, PreciseSession.class.getSimpleName() + " was null."));
    		}
    	} else if (Window.CANCEL != result) {
    	}
    	super.run();
    }
    

	/* (non-Javadoc)
	 * @see remato.client.view.session.ISessionHolder#disposeSession()
	 */
	public boolean disposeSession() {
		session = null;
		return true;
	}

	/* (non-Javadoc)
	 * @see remato.client.view.session.ISessionHolder#disposeSession(boolean)
	 */
	public boolean disposeSession(boolean saveChanges) {
		return disposeSession();
	}

	/* (non-Javadoc)
	 * @see remato.client.view.session.ISessionHolder#disposeSession(java.lang.String)
	 */
	public boolean disposeSession(String whySaveExplanation) {
		return disposeSession();
	}

	/* (non-Javadoc)
	 * @see remato.client.view.session.ISessionHolder#getSession()
	 */
	public ClientSession getSession() {
		throw new RematoClientException(new ModelStatus(IStatus.ERROR, "Internal error, this method should never be called.", new IllegalStateException()));
	}

	/* (non-Javadoc)
	 * @see remato.client.view.session.ISessionHolder#setSession(remato.client.controller.ClientSession)
	 */
	public boolean setSession(PreciseSession newSession) {
		this.session = newSession;
		return true;
	}

	/* (non-Javadoc)
	 * @see remato.client.view.session.ISessionHolder#isSessionSet()
	 */
	public boolean isSessionSet() {
		return null != session;
	}
	
}
